#include "lclog.h"
#include <deftype.h>
#include <eh.h>
#include "SearchCall.h"
void my_trans_func(unsigned int u, PEXCEPTION_POINTERS pExp )
{
	throw u;
}

typedef struct TAGmeminfo
{
	DWORD dwstart;
	DWORD dwsize;
}meminfo;
int g_nnocount = 0;
int g_ncount = 0;
int g_ndwexecutemax = 0;
int g_ndwnotexecutemax = 0;
meminfo * g_dwexecute = NULL;
meminfo * g_dwnoexecute = NULL;
void init_findcall()
{
	_set_se_translator(my_trans_func);
	SYSTEM_INFO SystemInfo;
	GetSystemInfo(&SystemInfo);
	MEMORY_BASIC_INFORMATION memory;
	DWORD dwBegin = (DWORD)SystemInfo.lpMinimumApplicationAddress;
	DWORD dwEnd = (DWORD)SystemInfo.lpMaximumApplicationAddress;
	DWORD dwstep = SystemInfo.dwPageSize;
	g_ndwexecutemax = sizeof(meminfo) * 1024 * 4;
	g_ndwnotexecutemax = sizeof(meminfo) * 1024 * 4;
	g_dwexecute = (meminfo *)malloc(g_ndwexecutemax);
	g_dwnoexecute = (meminfo *)malloc(g_ndwnotexecutemax);
	for(DWORD i = dwBegin;i<dwEnd;)
	{
		int nret = VirtualQuery((void *)i,&memory,
			SystemInfo.dwPageSize);
		if(((memory.AllocationProtect & PAGE_EXECUTE) == PAGE_EXECUTE) ||
			((memory.AllocationProtect & PAGE_EXECUTE_READ) == PAGE_EXECUTE_READ) ||
			((memory.AllocationProtect & PAGE_EXECUTE_READWRITE) == PAGE_EXECUTE_READWRITE) ||
			((memory.AllocationProtect & PAGE_EXECUTE_WRITECOPY) == PAGE_EXECUTE_WRITECOPY))
		{
			if(g_ncount > (g_ndwexecutemax /sizeof(meminfo)  - 1))
			{
				g_ndwexecutemax += sizeof(meminfo) * 1024 * 4;
				meminfo * dwexecutetemp = (meminfo *)malloc(g_ndwexecutemax);
				memcpy(dwexecutetemp,g_dwexecute,g_ndwexecutemax - sizeof(meminfo) * 1024 * 4);
				free(g_dwexecute);
				g_dwexecute = dwexecutetemp;
			}
			//PAGE_READWRITE
		//	g_dwexecute[g_ncount].dwstart = (DWORD)memory.AllocationBase;
			g_dwexecute[g_ncount].dwstart = i;
			g_dwexecute[g_ncount++].dwsize = memory.RegionSize;
			
			DWORD flOldProtect = memory.Protect | PAGE_READWRITE;
			DWORD flOldProtect2;
			VirtualProtectEx(::GetCurrentProcess(),(LPVOID)memory.BaseAddress,memory.RegionSize,flOldProtect, &flOldProtect2);
		//	mylog("address = %08x, memsize =  %08x,nret = %08x\r\n",
		//		i,memory.RegionSize,nret);
		}
		else if(memory.AllocationProtect)
		{
			if(g_nnocount > (g_ndwnotexecutemax /sizeof(meminfo)  - 1))
			{
				g_ndwnotexecutemax += sizeof(meminfo) * 1024 * 4;
				meminfo * dwexecutetemp2 = (meminfo *)malloc(g_ndwnotexecutemax);
				memcpy(dwexecutetemp2,g_dwnoexecute,g_ndwnotexecutemax - sizeof(meminfo) * 1024 * 4);
				free(g_dwnoexecute);
				g_dwnoexecute = dwexecutetemp2;
			}
			//g_dwnoexecute[g_nnocount].dwstart = (DWORD)memory.AllocationBase;
			g_dwnoexecute[g_nnocount].dwstart = i;
			g_dwnoexecute[g_nnocount++].dwsize = memory.RegionSize;
		}
		if(memory.AllocationProtect)
		{
			i+=memory.RegionSize;
		}
		else
		{
			i+=dwstep;
		}
		//mylog("address = %08x, memsize =  %08x,nret = %08x\r\n",
		//	i,memory.RegionSize,nret);
		memset(&memory,0,sizeof(MEMORY_BASIC_INFORMATION));
	}
}


void SeachCall() 
{
	// TODO: Add your control notification handler code here
	DWORD dwESP;
	DWORD dwESPEnd;
	_asm
	{
		MOV DWORD PTR[dwESP],esp;
	}
	for(int j = 0;j<g_nnocount;j++)
	{
		if(g_dwnoexecute[j].dwstart<dwESP && g_dwnoexecute[j].dwsize > (dwESP -g_dwnoexecute[j].dwstart))
		{
		//	mylog("address = %08x, memsize =  %08x,esp = %08x\r\n",dwnoexecute[j].dwstart,dwnoexecute[j].dwsize,dwESP);
			dwESPEnd = g_dwnoexecute[j].dwstart + g_dwnoexecute[j].dwsize;
		}
	}
	for(DWORD * DWesp = (DWORD * )dwESP;dwESPEnd>(DWORD)DWesp;DWesp++)
	{
		try
		{
			for(int j = 0;j<g_ncount;j++)
			{
				if(g_dwexecute[j].dwstart<*DWesp && g_dwexecute[j].dwsize > (*DWesp -g_dwexecute[j].dwstart))
				{
					uint8 * pdata = (uint8 *)*DWesp;
					pdata -=6;
					if(pdata[1] == 0xe8)
					{
						mylog("%08x ",*DWesp);
					}
					else if(pdata[1] == 0x9a)
					{
						mylog("%08x ",*DWesp);
					}
					else
					{
					}
					
				}
			}
		}
		catch(...)
		{}
	}
	mylog("\r\n");
}